﻿using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business.Reports;
using NP.BPMReportPlatform.Reports.CommonApprovalProcessReport.Dtos;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace NP.BPMReportPlatform.Reports.CommonApprovalProcessReport
{
    public static class ExpressionEx
    {
        public static string GetConfigFiledCombine(this List<CommonApprovalProcessConfig> data, FieldEnum SortIndex)
        {
            return data.FirstOrDefault(x => x.SortIndex == (int)SortIndex)?.FieldCombine ?? "";
        }

        public static ISugarQueryable<GetCommonApprovalProcessOutput> AddQueryForEach(
            this ISugarQueryable<GetCommonApprovalProcessOutput> listQueryable,
            List<FieldsSearchModel> searchItems)
        {
            if (searchItems.Any())
            {
                searchItems = searchItems.OrderBy(x => x.SortIndex).ToList();
                searchItems.ForEach(x =>
                {
                    listQueryable = listQueryable.AddQuery(x);
                });
            }
            return listQueryable;
        }

        private static ISugarQueryable<GetCommonApprovalProcessOutput> AddQuery(
            this ISugarQueryable<GetCommonApprovalProcessOutput> listQueryable,
            FieldsSearchModel x)
        {
            var fieldName = GetFieldName(x.SortIndex);
            if (x.SortIndex <= (int)FieldEnum.Text20 && x.SortIndex >= (int)FieldEnum.Text1 &&
                (!string.IsNullOrEmpty(x.SearchStr) || !string.IsNullOrEmpty(x.StartTime) &&
                !string.IsNullOrEmpty(x.EndTime) || x.SearchArr.Any()))
            {
                if (string.IsNullOrEmpty(fieldName))
                {
                    return listQueryable;
                }
                if (x.FieldType?.ToLower() == "date")
                {
                    if (!string.IsNullOrEmpty(x.StartTime) && !string.IsNullOrEmpty(x.EndTime) &&
                        DateTime.TryParse(x.StartTime, out DateTime StartTime) &&
                        DateTime.TryParse(x.EndTime, out DateTime EndTime))
                    {
                        listQueryable = listQueryable.
                            Where(@$" STR_TO_DATE({fieldName}, '%Y-%m-%d %H:%i:%s') <= @EndTime AND 
                                    STR_TO_DATE({fieldName}, '%Y-%m-%d %H:%i:%s') >= @StartTime ", 
                                    new { StartTime, EndTime });
                    }
                }
                else if (x.FieldType?.ToLower() == "select-multiple")
                {
                    listQueryable = listQueryable.Where($" {fieldName} IN (@SearchArr) ", new { x.SearchArr });
                }
                else
                {
                    listQueryable = x.IsAccurate ?
                        listQueryable.Where($" {fieldName}=@SearchStr ", new { x.SearchStr }) :
                        listQueryable.Where($" {fieldName} like @SearchStr ", new { SearchStr = $"%{x.SearchStr}%" });
                }
            }
            else if((x.SortIndex <= (int)FieldEnum.TextArea4 && x.SortIndex >= (int)FieldEnum.TextArea1 ||
                x.SortIndex == (int)FieldEnum.Topic || x.SortIndex == (int)FieldEnum.InstanceNumber ||
                x.SortIndex == (int)FieldEnum.StartUserName) && !string.IsNullOrEmpty(x.SearchStr))
            {
                listQueryable = x.IsAccurate ?
                    listQueryable.Where($" {fieldName}=@SearchStr ", new { x.SearchStr }) :
                    listQueryable.Where($" {fieldName} like @SearchStr ", new { SearchStr = $"%{x.SearchStr}%" });
            }
            else if(x.SortIndex == (int)FieldEnum.StartTime &&
                !string.IsNullOrEmpty(x.StartTime) && !string.IsNullOrEmpty(x.EndTime))
            {
                if (!string.IsNullOrEmpty(x.StartTime) && !string.IsNullOrEmpty(x.EndTime) &&
                    DateTime.TryParse(x.StartTime, out DateTime StartTime) &&
                    DateTime.TryParse(x.EndTime, out DateTime EndTime))
                {
                    listQueryable = listQueryable.
                            Where($" {fieldName} <= @EndTime AND {fieldName} >= @StartTime ",
                            new { StartTime, EndTime });
                }
            }
            else if(x.SortIndex == (int)FieldEnum.StatusCode && x.SearchArr.Any())
            {
                listQueryable = listQueryable.Where($" {fieldName} IN (@SearchArr) ",
                        new { x.SearchArr });
            }

            return listQueryable;
        }

        private static string GetFieldName(int sortIndex)
        {
            return sortIndex switch
            {
                (int)FieldEnum.Text1 => "Text1",
                (int)FieldEnum.Text2 => "Text2",
                (int)FieldEnum.Text3 => "Text3",
                (int)FieldEnum.Text4 => "Text4",
                (int)FieldEnum.Text5 => "Text5",
                (int)FieldEnum.Text6 => "Text6",
                (int)FieldEnum.Text7 => "Text7",
                (int)FieldEnum.Text8 => "Text8",
                (int)FieldEnum.Text9 => "Text9",
                (int)FieldEnum.Text10 => "Text10",
                (int)FieldEnum.Text11 => "Text11",
                (int)FieldEnum.Text12 => "Text12",
                (int)FieldEnum.Text13 => "Text13",
                (int)FieldEnum.Text14 => "Text14",
                (int)FieldEnum.Text15 => "Text15",
                (int)FieldEnum.Text16 => "Text16",
                (int)FieldEnum.Text17 => "Text17",
                (int)FieldEnum.Text18 => "Text18",
                (int)FieldEnum.Text19 => "Text19",
                (int)FieldEnum.Text20 => "Text20",
                (int)FieldEnum.TextArea1 => "TextArea1",
                (int)FieldEnum.TextArea2 => "TextArea2",
                (int)FieldEnum.TextArea3 => "TextArea3",
                (int)FieldEnum.TextArea4 => "TextArea4",
                (int)FieldEnum.StartTime => "StartTime",
                (int)FieldEnum.InstanceNumber => "InstanceNumber",
                (int)FieldEnum.Topic => "Topic",
                (int)FieldEnum.StatusCode => "StatusCode",
                (int)FieldEnum.StartUserName => "StartUserName",
                _ => null,
            };
        }
    }
}
